#include "Object.h"
#include <assert.h>

Object::Object()
	: _references(1)
	, _autorelease(false)
{
}

void Object::autorelease()
{
	assert(_autorelease == false);
	_autorelease = true;
	AutoreleasePool::getInstance()->addObject(this);
}

void Object::release()
{
	assert(_references > 0);
	_references--;
	if (_references == 0)
	{
		delete this;
	}
}

void Object::retain()
{
	_references++;
}

Object::~Object()
{
	if (_autorelease)
		AutoreleasePool::getInstance()->removeObject(this);
}


AutoreleasePool* AutoreleasePool::_instance = nullptr;

AutoreleasePool* AutoreleasePool::getInstance()
{
	if (_instance == nullptr)
		_instance = new AutoreleasePool();
	return _instance;
}

void AutoreleasePool::addObject(Object* o)
{
	_pool.push_back(o);
}

void AutoreleasePool::check()
{
	if (!_isPause && _pool.size() > 0)
	{
		std::vector<Object*> copies = _pool;
		_pool.clear();
		for (Object* o : copies)
		{
			o->release();
		}
	}
}

void AutoreleasePool::removeObject(Object* o)
{
	auto find = std::find(_pool.begin(), _pool.end(), o);
	if (find != _pool.end())
		_pool.erase(find);
}
